/**********************************************************************************************************
** 驱动文件：	ups-C6_20KS.c
** 驱动类型：	ups
** 设备名称：	UPS监测
** 设备型号：	C6_20KS
** 设备品牌：	山特
** 设备协议：	RS232通讯协议
** 驱动描述：	适用于山特梦幻城堡CASTLE系列UPS产品，包括：C6K、C6KS、C10K、C10KS、3C10KS、3C15KS、3C20KS等机型。
** 生成日期：	2018-05-17 17:35:06
**********************************************************************************************************/
#include "Includes.h"


/**********************************************************************************************************
* 定义设备数据点变量结构
**********************************************************************************************************/
typedef struct{
	Var inputUA;								//A相入电压
	Var inputUB;								//B相入电压
	Var inputUC;								//C相入电压
	Var inputFreq;								//输入频率
	Var outputUA;								//A相出电压
	Var outputUB;								//B相出电压
	Var outputUC;								//C相出电压
	Var outputFreq;								//输出频率
	Var batVolt;								//电池电压
	Var temp;									//温度
	Var batTimeRemaining;						//后备时间
	Var batCapacity;							//电池容量
	Var sysModel;								//系统模式
	Var batTestState;							//电池测试状态
	Var outputPA;								//A相有功功率
	Var outputPB;								//B相有功功率
	Var outputPC;								//C相有功功率
	Var outputSA;								//A相视在功率
	Var outputSB;								//B相视在功率
	Var outputSC;								//C相视在功率
	Var Psum;									//总有功功率
	Var Ssum;									//总视在功率
	Var outputIA;								//A相电流
	Var outputIB;								//B相电流
	Var outputIC;								//C相电流
	Var loadPerc;								//负载率
	Var electricityState;						//市电状态
	Var batLowVolt;								//电池电压状态
	Var bypassModel;							//旁路模式
	Var upsFault;								//UPS故障
	Var runType;								//运行类型
	Var testProgress;							//测试进度
	Var onoff;									//开/关机
}Data_Struct;									//定义变量结构


/**********************************************************************************************************
* 设备数据点变量属性声明
**********************************************************************************************************/
const static Var_Property_Def var_attr[] = {
	{
		FLOAT,
		0,
		READONLY,
		"inputUA",
		"A相入电压",
		"V",
		"A相输入电压",
		0,
		0,
		"A相输入电压过高",
		"A相输入电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"inputUB",
		"B相入电压",
		"V",
		"B相输入电压",
		0,
		0,
		"B相输入电压过高",
		"B相输入电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"inputUC",
		"C相入电压",
		"V",
		"C相输入电压",
		0,
		0,
		"C相输入电压过高",
		"C相输入电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"inputFreq",
		"输入频率",
		"Hz",
		"输入频率",
		0,
		0,
		"输入频率过高",
		"输入频率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputUA",
		"A相出电压",
		"V",
		"A相出电压",
		0,
		0,
		"A相输出电压过高",
		"A相输出电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputUB",
		"B相出电压",
		"V",
		"B相出电压",
		0,
		0,
		"B相输出电压过高",
		"B相输出电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputUC",
		"C相出电压",
		"V",
		"C相出电压",
		0,
		0,
		"C相输出电压过高",
		"C相输出电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputFreq",
		"输出频率",
		"Hz",
		"输出频率",
		0,
		0,
		"输出频率过高",
		"输出频率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"batVolt",
		"电池电压",
		"V",
		"电池电压",
		0,
		0,
		"电池电压过高",
		"电池电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"temp",
		"温度",
		"℃",
		"温度",
		0,
		0,
		"电池电压过高",
		"电池电压过低",
		0,
		0
	},
	{
		INTEGER,
		0,
		READONLY,
		"batTimeRemaining",
		"后备时间",
		"分",
		"电池剩余供电时间",
		0,
		0,
		"电池剩余供电时间过高",
		"电池剩余供电时间过低",
		0,
		0
	},
	{
		INTEGER,
		0,
		READONLY,
		"batCapacity",
		"电池容量",
		"%",
		"电池容量",
		0,
		0,
		"电池容量过高",
		"电池容量过低",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"sysModel",
		"系统模式",
		"",
		"系统模式:上电初始、待机模式、旁路模式、在线模式、后备模式、电池测试、故障模式、变频模式、高效模式、关机模式",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"batTestState",
		"电池测试状态",
		"",
		"电池测试状态:0-完成,1-进行中,2-正常,3-故障,4-Not possible,5-测试取消,6-其他",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputPA",
		"A相有功功率",
		"KW",
		"A相有功功率",
		0,
		0,
		"A相有功功率过高",
		"A相有功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputPB",
		"B相有功功率",
		"KW",
		"B相有功功率",
		0,
		0,
		"B相功率有功过高",
		"B相功率有功过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputPC",
		"C相有功功率",
		"KW",
		"C相输出有功功率",
		0,
		0,
		"C相功率有功过高",
		"C相功率有功过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputSA",
		"A相视在功率",
		"KVA",
		"A相视在功率",
		0,
		0,
		"A相视在功率过高",
		"A相视在功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputSB",
		"B相视在功率",
		"KVA",
		"B相视在功率",
		0,
		0,
		"B相视在功率过高",
		"B相视在功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputSC",
		"C相视在功率",
		"KVA",
		"C相视在功率",
		0,
		0,
		"C相视在功率过高",
		"C相视在功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Psum",
		"总有功功率",
		"KW",
		"总有功功率",
		0,
		0,
		"总功率过高",
		"总功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ssum",
		"总视在功率",
		"KVA",
		"总视在功率",
		0,
		0,
		"总视在功率过高",
		"总视在功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputIA",
		"A相电流",
		"A",
		"A相输出电流",
		0,
		0,
		"A相输出电流过高",
		"A相输出电流过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputIB",
		"B相电流",
		"A",
		"B相输出电流",
		0,
		0,
		"B相输出电流过高",
		"B相输出电流过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"outputIC",
		"C相电流",
		"A",
		"C相输出电流",
		0,
		0,
		"C相输出电流过高",
		"C相输出电流过低",
		0,
		0
	},
	{
		INTEGER,
		0,
		READONLY,
		"loadPerc",
		"负载率",
		"%",
		"输出负载百分比",
		0,
		0,
		"输出负载过高",
		"输出负载过低",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"electricityState",
		"市电状态",
		"",
		"市电状态:0-正常，1-异常",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"batLowVolt",
		"电池电压状态",
		"",
		"电池电压低:0-正常，1-低压",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"bypassModel",
		"旁路模式",
		"",
		"旁路模式:0-关闭，1-启动",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"upsFault",
		"UPS故障",
		"",
		"UPS故障:0-无，1-发生",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"runType",
		"运行类型",
		"",
		"运行类型:0-在线式，1-后备式",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"testProgress",
		"测试进度",
		"",
		"测试进度:0-完成，1-进行中",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"onoff",
		"开/关机",
		"",
		"开关机状态:0-开机，1-关机",
		0,
		0,
		"",
		"",
		0,
		0
	}
};


/**********************************************************************************************************
* 函数名称： static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
* 函数说明： 生成获取传感器数据指令
* 输入参数： 指令索引，传感器地址，变量结构体指针,以及指令缓存区指针,指令长度
* 返回参数： 无
**********************************************************************************************************/
static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
{
	switch(index)
	{
		case 0:
			*len = sprintf(cmd,"Q6\r");
			break;
		case 1:
			*len = sprintf(cmd,"WA\r");
			break;		
		default:
			break;
	}
}


/**********************************************************************************************************
* 函数名称： static int parse_fun(short index, int addr, void *data, char *buf, short len)
* 函数说明： 解析传感器响应的数据，并写入数据库
* 输入参数： 解析索引,传感器地址，变量结构体指针，以及响应数据缓存取指针，响应数据长度
* 返回参数： 返回解析结果，返回0成功，返回1失败
**********************************************************************************************************/
static int parse_fun(short index, int addr, void *data, char *buf, short len)
{
	const char *sysmodel[] = {"上电初始","待机模式","旁路模式","在线模式","后备模式","电池测试","故障模式","变频模式","高效模式","关机模式"};
	const char *batTestState[] = {"完成","进行中","正常","故障","Not possible","测试取消","其他"};
	int   i;
//	float f;
	Data_Struct 	*d = (Data_Struct*)data;
	buf[len] = '\0';
	if(buf!=NULL && buf[0]=='(' && len>0 && buf[len-1]=='\r')
	{	
		switch(index)
		{
			case 0:
				buf[85] ='\0';
				for(i=0; buf[i]!='\0'; i++)
				{
					if(buf[i]=='-') buf[i]='0';
				}
				
				d->inputUA.value.fnum = atof(buf+1);
				d->inputUB.value.fnum = atof(buf+7);
				d->inputUC.value.fnum = atof(buf+13);
				d->inputFreq.value.fnum = atof(buf+19);
				d->outputUA.value.fnum = atof(buf+24);
				d->outputUB.value.fnum = atof(buf+30);
				d->outputUC.value.fnum = atof(buf+36);
				d->outputFreq.value.fnum = atof(buf+42);				
				d->batVolt.value.fnum = atof(buf+59);
				d->temp.value.fnum = atof(buf+71);
				d->batTimeRemaining.value.inum = atoi(buf+76)/60;
				d->batCapacity.value.inum = atoi(buf+82);				

//				sscanf(buf,"(%f %f %f %f %f %f %f %f %d %d %d %f %f %f %d %d",
//					&d->inputUA.value.fnum,
//					&d->inputUB.value.fnum,
//					&d->inputUC.value.fnum,
//					&d->inputFreq.value.fnum,
//					&d->outputUA.value.fnum,
//					&d->outputUB.value.fnum,
//					&d->outputUC.value.fnum,
//					&d->outputFreq.value.fnum,
//					&i,
//					&i,
//					&i,
//					&d->batVolt.value.fnum,
//					&f,
//					&d->temp.value.fnum,
//					&d->batTimeRemaining.value.inum,
//					&d->batCapacity.value.inum);
				
					i = buf[86]-0x30;
					d->sysModel.value.str = sysmodel[i];
					Set_Var_Status(&d->sysModel, i==6?Alarm:Normal, NULL);	
					i = buf[87]-0x30;
					i = i<6?i:6;
					d->batTestState.value.str = batTestState[i];
					Set_Var_Status(&d->batTestState, i==3?Alarm:Normal, NULL);						
				break;
			case 1:
				buf[70] ='\0';
				for(i=0; buf[i]!='\0'; i++)
				{
					if(buf[i]=='-') buf[i]='0';
				}
				d->outputPA.value.fnum = atof(buf+1);
				d->outputPB.value.fnum = atof(buf+7);
				d->outputPC.value.fnum = atof(buf+13);
				d->outputSA.value.fnum = atof(buf+19);
				d->outputSB.value.fnum = atof(buf+25);
				d->outputSC.value.fnum = atof(buf+31);
				d->Psum.value.fnum = atof(buf+37);
				d->Ssum.value.fnum = atof(buf+43);			
				d->outputIA.value.fnum = atof(buf+49);
				d->outputIB.value.fnum = atof(buf+55);
				d->outputIC.value.fnum = atof(buf+61);				
				d->loadPerc.value.inum = atoi(buf+67);				

//				sscanf(buf,"(%f %f %f %f %f %f %f %f %f %f %f %d",
//					&d->outputPA.value.fnum,
//					&d->outputPB.value.fnum,
//					&d->outputPC.value.fnum,
//					&d->outputSA.value.fnum,
//					&d->outputSB.value.fnum,
//					&d->outputSC.value.fnum,
//					&d->Psum.value.fnum,
//					&d->Ssum.value.fnum,				
//					&d->outputIA.value.fnum,
//					&d->outputIB.value.fnum,
//					&d->outputIC.value.fnum,				
//					&d->loadPerc.value.inum
//				);
				d->electricityState.value.str = buf[71]=='1'?"异常":"正常";
				Set_Var_Status(&d->electricityState, buf[71]=='1'?Alarm:Normal, NULL);	
				d->batLowVolt.value.str = buf[72]=='1'?"低压":"正常";
				Set_Var_Status(&d->batLowVolt, buf[72]=='1'?Alarm:Normal, NULL);					
				d->bypassModel.value.str = buf[73]=='1'?"开启":"关闭";
				Set_Var_Status(&d->bypassModel, buf[73]=='1'?Alarm:Normal, NULL);					
				d->upsFault.value.str = buf[74]=='1'?"发生":"无";
				Set_Var_Status(&d->upsFault, buf[74]=='1'?Alarm:Normal, NULL);						
				d->runType.value.str = buf[75]=='1'?"后备式":"在线式";
				Set_Var_Status(&d->runType, buf[75]=='1'?Alarm:Normal, NULL);					
				d->testProgress.value.str = buf[76]=='1'?"进行中":"完成";
				
				d->onoff.value.str = buf[77]=='1'?"关机":"开机";	
				Set_Var_Status(&d->onoff, buf[77]=='1'?Alarm:Normal, NULL);				

				break;		
			default:
				break;
		}
		return 0;
	}
	return 1;
}


/**********************************************************************************************************
* 函数名称： void ups_C6_20KS_Registration(void)
* 函数说明： UPS监测驱动注册
* 输入参数： 无
* 返回参数： 无
**********************************************************************************************************/
void ups_C6_20KS_Registration(void)
{
	DeviceDriverRegistration(
		"ups",													//设备类型
		"UPS监测",												//设备名称（导航栏默认显示名称）
		"山特",													//设备品牌		
		"C6_20KS",												//设备型号
		"适用于山特梦幻城堡CASTLE系列UPS产品，包括：C6K、C6KS、C10K、C10KS、3C10KS、3C15KS、3C20KS等机型。",//驱动描述
		var_attr,												//变量属性声明
		sizeof(Data_Struct),									//变量结构体空间大小
		cmd_fun,												//发送指令生成函数
		parse_fun,												//数据解析函数
		1000													//设备响应超时时间		
	);
}

